import os
import sys
import time

import math
import subprocess

sys.path.append('pp')
import pp


class RunningMethod(object):
    def __init__(self, args, max_processes):
      self.args = args
      self.commands = []
      self.max_processes = max_processes

    def addCommand(self, cmd) :
      self.commands.append(cmd)

class RunningMethod_fork(RunningMethod):
    def run(self):
        nbProcesses = 0
        processes = {}
        allCmds = self.commands
        cmds = iter(allCmds)
        nbCmds = 0
        maxCmds = len(allCmds)

        start_t = time.time()
        while 1:
            if nbProcesses < self.max_processes:
                try:
                  currentCmd = allCmds[nbCmds]
                  args = currentCmd.split()
                  pid = os.fork()
                  if pid == 0:
                    os.execlp(args[0], *args)
                  else:
                    nbCmds += 1
                    print >>sys.stderr, "+ %4d/%4d "%(nbCmds, maxCmds)
                    processes[pid] = (currentCmd, time.time())
                    nbProcesses += 1
                except IndexError, e:
                    pass
            pid, res = os.waitpid(0, os.WNOHANG)
            if pid > 0:
              cmd, t = processes[pid]
              nbProcesses -= 1
              if nbProcesses == 0:
                if nbCmds >= len(allCmds):
                    break
            time.sleep(0.1)

def runProcess(cmd):
  split_cmd = cmd.split(' ')
#  split_cmd = ['python', '-c', 'import numpy; print numpy.version.version']
  import subprocess
  a = subprocess.check_output(split_cmd)
  return a.strip(" \n\r\t")

class RunningMethod_pp(RunningMethod):
    def __init__(self, args, max_processes, tuple_servers = ()):
        RunningMethod.__init__(self, args, max_processes)
        if self.max_processes > 0 :
          self.jobServer = pp.Server(self.max_processes,ppservers=tuple_servers)
        else :
          self.jobServer = pp.Server(ppservers=tuple_servers)

    def run(self):
        start_t = time.time()
        maxCmds = len(self.commands)
        allJobs = []
        for nbCmds, cmd in enumerate(self.commands):
#            nbcmds = nbCmds+1
#            (f1, f2), f_out = cmd
#            job = self.jobServer.submit(runProcess, (cmd,), (check_output,),('subprocess',))
            job = self.jobServer.submit(runProcess, (cmd,))
            allJobs.append(job)
        res = [job() for job in allJobs]
        self.jobServer.print_stats()
        return res

    def destroy(self) :
      self.jobServer.destroy()
